# !/usr/bin/env python
# encoding: utf-8


"""
  @author: gaogao
  @file: color_util.py
  @time: 2020/12/21 12:14
  @desc:
"""

import colorsys
import random
import numpy as np
import matplotlib as mpl

import matplotlib.pyplot as plt


def get_n_hls_colors(num):
    hls_colors = []
    i = 0
    step = 360.0 / num
    while i < 360:
        h = i
        var = random.random()
        s = 90 + var * 10
        l = 50 + var * 10
        _hlsc = [h / 360.0, l / 100.0, s / 100.0]
        hls_colors.append(_hlsc)
        i += step
    return hls_colors


def ncolors(num):
    rgb_colors = []
    if num < 1:
        return rgb_colors
    hls_colors = get_n_hls_colors(num)
    for hlsc in hls_colors:
        _r, _g, _b = colorsys.hls_to_rgb(hlsc[0], hlsc[1], hlsc[2])
        r, g, b = [int(x * 255.0) for x in (_r, _g, _b)]

        rgb_colors.append(color((r, g, b)))
    return rgb_colors


def color(value):
    digit = list(map(str, range(10))) + list("ABCDEF")
    if isinstance(value, tuple):
        string = '#'
        for i in value:
            a1 = i // 16
            a2 = i % 16
            string += digit[a1] + digit[a2]
        return string
    elif isinstance(value, str):
        a1 = digit.index(value[1]) * 16 + digit.index(value[2])
        a2 = digit.index(value[3]) * 16 + digit.index(value[4])
        a3 = digit.index(value[5]) * 16 + digit.index(value[6])
        return a1, a2, a3


def hex2rgb(hex):
    hex_cleaned = hex.lstrip('#')
    return tuple(int(hex_cleaned[i:i + 2], 16) for i in (0, 2, 4))


# rgb (tuple3) to hex (string)
def rgb2hex(rgb):
    return '#' + ''.join([str('0' + hex(hh)[2:])[-2:] for hh in rgb])


def color_mixer(hex1, hex2, wt1=0.5):
    rgb1 = hex2rgb(hex1)
    rgb2 = hex2rgb(hex2)
    return rgb2hex(tuple([int(wt1 * tup[0] + (1.0 - wt1) * tup[1]) for tup in zip(rgb1, rgb2)]))


# create full palette 根据起始、终止和中间的三个颜色，生成渐变色
def create_palette(start_color, mid_color, end_color, num_colors):
    # set up steps
    # will create twice as many colors as asked for
    # to allow an explicit "mid_color" with both even and odd number of colors
    num_steps = num_colors
    steps = np.linspace(0, 1, num_steps)[::-1]
    # create two halves of color values
    pt1 = [color_mixer(start_color, mid_color, wt) for wt in steps]
    pt2 = [color_mixer(mid_color, end_color, wt) for wt in steps[1:]]
    # combine and subsample to get back down to 'num_colors'
    return (pt1 + pt2)[::2]


def get_colors(name="YlOrRd", lut=50):
    return list(plt.get_cmap(name, lut)([i for i in range(lut)]))


def colorFader(c1, c2, mix=0):  # fade (linear interpolate) from color c1 (at mix=0) to c2 (mix=1)
    c1 = np.array(mpl.colors.to_rgb(c1))
    c2 = np.array(mpl.colors.to_rgb(c2))
    return mpl.colors.to_hex((1 - mix) * c1 + mix * c2)


def create_custome_palette(start_color="#FFFF66", end_color="#CC3333", num_colors=26):
    # set up steps
    # will create twice as many colors as asked for
    # to allow an explicit "mid_color" with both even and odd number of colors
    num_steps = num_colors
    steps = np.linspace(1, 10, num_steps)[::-1]
    # create two halves of color values
    pt1 = [color_mixer(start_color, end_color, wt) for wt in steps]
    # combine and subsample to get back down to 'num_colors'
    return pt1


# print((get_colors("Oranges",50)))

# print(ncolors(12))
